/**
 * @file fun.c 服务器端函数实现
 *  
 * @author pzk (1528089905@qq.com)
 * @brief 
 * @version 1.5
 * @date 2025-8-25
 * 
 * @copyright copyright (c) 2025
 */
#include "server.h"

// 初始化服务器函数
void init_server()
{
    struct sockaddr_in server_addr;
    int ret;
    
    // 初始化用户链表和互斥锁
    users_list = create_dlist();
    SYSERR2(NULL, ==, users_list, "users_list is NULL", exit(EXIT_FAILURE));
    online_list = create_dlist();
    SYSERR2(NULL, ==, online_list, "online_list is NULL", exit(EXIT_FAILURE));
    pthread_mutex_init(&users_mutex, NULL); 

    // 服务器启动时加载用户数据
    load_users_from_file();

    // 创建TCP套接字
    server_sock = socket(AF_INET, SOCK_STREAM, 0);
    SYSERR(server_sock, ==, -1, "socket failed",);
    
    // 设置地址可重用
    int opt = 1;
    setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    
    // 设置服务器地址
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(PORT);
    
    // 绑定地址
    ret = bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
    SYSERR(ret, ==, -1, "bind failed", );
    
    // 开始监听
    ret = listen(server_sock, 10);
    SYSERR(ret, ==, -1, "listen failed",);
}


// 保存用户数据函数
void save_users_to_file(node_t *head) 
{
    SYSERR(NULL, ==, users_list, "users_list is NULL", );

    FILE *file = fopen(USER_FILE, "w");
    SYSERR(NULL, ==, file, "open file failed", );

    pthread_mutex_lock(&users_mutex);

    // 重新计算设备数量并更新序号
	int order = 1;
	node_t *temp = head->after;
	while(temp != head) 
	{
		((users_t *)temp->data)->user_order = order++; 
		temp = temp->after;
	}

	// 更新总数量
	user_count= order - 1;  
    // 写入第一行：下一个最小ID  写入第二行：用户总数
    fprintf(file, "%d\n%d\n", user_id_min, user_count);

    // 遍历链表
    temp = head->after;
    while (temp != head) 
    {  
        if (!temp->data) 
        {
            temp = temp->after;
            continue;
        }

        users_t *user = (users_t *)temp->data;
        fprintf(file, "%d %d %.*s %.*s %d %c %.*s %.*s %.*s %d %d %d\n",
                user->user_id,
                user->user_order,
                31, user->user_name,  
                15, user->user_pw,
                user->user_age,
                user->sex,
                15, user->user_phone,
                31, user->user_email,
                15, user->user_place,
                user->user_state,
                user->user_friend_num,
                user->user_group_num);

        temp = temp->after;  // 移动到下一个节点
    }

    pthread_mutex_unlock(&users_mutex);
    fclose(file);
    printf("[HINT]User data save success to %s\n", USER_FILE);
}


// 加载用户数据函数
void load_users_from_file() 
{
    FILE *file = fopen(USER_FILE, "r");  
    if (!file) 
    {   
        // 文件不存在，初始化
        file = fopen(USER_FILE, "w+");
        fprintf(file, "1000\n0\n"); 
        fclose(file);
        return ;
    }
    
    pthread_mutex_lock(&users_mutex);  
    
    // 第一行：读取下一个最小ID
    if (fscanf(file, "%d\n", &user_id_min) != 1) 
    {
        SYSERR2(NULL, ==, file, "User data loading error（ID）", fclose(file);pthread_mutex_unlock(&users_mutex);return);
    }
    // 第二行：读取用户总数
    if (fscanf(file, "%d\n", &user_count) != 1) 
    {
        SYSERR2(NULL, ==, file, "User data loading error（COUNT）", fclose(file);pthread_mutex_unlock(&users_mutex);return);
    }
    
    // 从第三行开始：读取每个用户数据
    users_t user;
    int actual_loaded = 0; 
    for (int i = 0; i < user_count; i++) 
    {
        fscanf(file, 
        "%d %d %s %s %d %c %s %s %s %d %d %d",  
        &user.user_id,          // 1. 用户ID（数字）
        &user.user_order,       // 2. 排序号（数字）
        user.user_name,         // 3. 用户名（字符串）
        user.user_pw,           // 4. 密码（字符串）
        &user.user_age,         // 5. 年龄（数字）
        &user.sex,              // 6. 性别（字符，%c前加空格跳过可能的空格）
        user.user_phone,        // 7. 手机号（字符串）
        user.user_email,        // 8. 邮箱（字符串）
        user.user_place,        // 9. 居住地（字符串）
        &user.user_state,       // 10. 状态（数字）
        &user.user_friend_num,  // 11. 好友数（数字）
        &user.user_group_num    // 12. 群聊数（数字）
        );
        // 插入链表
        if (insert_tdlist(users_list, &user, sizeof(users_t)) == 0) 
        {
            actual_loaded++;
            //printf("[Load Test] ID：%d，Name：%s，Password：%s，age：%d\n",user.user_id,user.user_name, user.user_pw, user.user_age);
        }
    }
    
    pthread_mutex_unlock(&users_mutex);
    fclose(file);
    printf("[HINT] Loading success %d userdata，next ID is: %d\n", user_count, user_id_min);
}


// 处理请求函数
void *handle_client(void *arg)
{
    int client_fd = *(int *)arg;  
    free(arg);  // 释放动态分配的内存
    
    char buf[1024] = {0};
    ssize_t recv_len;
    struct sockaddr_in client_addr;
    socklen_t addr_len = sizeof(client_addr);
    getpeername(client_fd, (struct sockaddr*)&client_addr, &addr_len);

    while(1)
    {
        memset(buf, 0, sizeof(buf));
        recv_len = recv(client_fd, buf, sizeof(buf)-1, 0);
        
        // 处理客户端断开连接
        if (recv_len <= 0) 
        {
            if (recv_len < 0) 
                perror("recv failed");
            printf("Client %d disconnet\n", client_fd);
            close(client_fd);
            pthread_exit(NULL);
        }

        buf[recv_len] = '\0';
        printf("[SERVER] Received command %s from client %d\n", buf, client_fd);
        if (strstr(buf, PRIVATE_REQUEST) == buf)  //私聊请求
        {
            handle_private_request(client_fd, buf);
        }
        else if (strstr(buf, PRIVATE_MSG) == buf) //私聊信息
        {
            handle_private_msg(client_fd, buf);     
        }
        else if (strstr(buf, PRIVATE_EXIT) == buf) //私聊退出
        {
            handle_private_exit(client_fd, buf);
        }
        else if (strstr(buf, PRIVATE_ACCEPT) == buf) //私聊接受
        {
            handle_private_accept(client_fd, buf);
        }
        else if (strstr(buf, PRIVATE_REFUSE) == buf) //私聊拒绝
        {
            handle_private_refuse(client_fd, buf);
        }
        else if (strstr(buf, USER_INFO_CMD) == buf) // 查看用户信息请求
        {
            handle_user_info(client_fd, buf);
        }
        else if (strstr(buf, REGISTER_CMD) == buf) //注册请求
        {
            handle_register(client_fd, buf);
        } 
        else if (strstr(buf, LOGIN_CMD) == buf) //登陆请求
        {
            handle_login(client_fd, buf);
        } 
        else if (strstr(buf, DELETE_CMD) == buf) //删除请求
        {
            handle_delete(client_fd, buf); 
        }
        else if (strstr(buf, SHOW_USER_CMD) == buf) //显示用户请求
        {  
            handle_show_user(client_fd, buf);
        }
        else if (strstr(buf, FIND_USER_CMD) == buf) //查找请求
        {  
            handle_find(client_fd, buf);
        }
        else if (strstr(buf, LOGOUT_CMD) == buf) //登出请求
        {
            handle_logout(client_fd, buf);
            close(client_fd);
            pthread_exit(NULL);
        }
        else if (strstr(buf, ONLINE_CMD) == buf) //显示在线用户请求
        {
            handle_get_online(client_fd);  
        }
        else if (strstr(buf, QUIT_CMD) == buf) //退出请求
        {
            send(client_fd, "QUIT_ACK", strlen("QUIT_ACK"), 0);
            printf("[SERVER]Client %d requests to exit\n", client_fd);
            close(client_fd);
            pthread_exit(NULL);
        }
        else 
        {
            send(client_fd, "UNKNOWN_CMD", strlen("UNKNOWN_CMD"), 0);
            printf("[HINT]Client %d send unknown command:%s\n", client_fd, buf);
        }
    }
}


// 注册请求处理函数
void handle_register(int client_fd, const char *data) 
{
    users_t new_user = {0};
    char *info = strdup(data + strlen(REGISTER_CMD));
    
    // 解析注册信息：用户名|密码|年龄|性别|手机号|邮箱|居住地
    char *token = strtok(info, "|");
    if (token) strncpy(new_user.user_name, token, sizeof(new_user.user_name)-1);
    token = strtok(NULL, "|");
    if (token) strncpy(new_user.user_pw, token, sizeof(new_user.user_pw)-1);
    token = strtok(NULL, "|");
    if (token) new_user.user_age = atoi(token);
    token = strtok(NULL, "|");
    if (token) new_user.sex = token[0];
    token = strtok(NULL, "|");
    if (token) strncpy(new_user.user_phone, token, sizeof(new_user.user_phone)-1);
    token = strtok(NULL, "|");
    if (token) strncpy(new_user.user_email, token, sizeof(new_user.user_email)-1);
    token = strtok(NULL, "|");
    if (token) strncpy(new_user.user_place, token, sizeof(new_user.user_place)-1);
    token = strtok(NULL, "|");
    if (token) new_user.user_friend_num = atoi(token);
    token = strtok(NULL, "|");
    if (token) new_user.user_group_num = atoi(token);

    // 服务器分配用户ID和排序号
    pthread_mutex_lock(&users_mutex);
    new_user.user_id = user_id_min++;
    new_user.user_order = ++user_count;
    new_user.user_state = 0;  
    
    // 插入到链表尾部
    insert_tdlist(users_list, &new_user, sizeof(users_t));
    pthread_mutex_unlock(&users_mutex);
    
    // 返回注册结果
    char response[64];
    //格式 ：REGISTER_SUCCESS | ID
    snprintf(response, sizeof(response), "REGISTER_SUCCESS | ID:%d", new_user.user_id);
    send(client_fd, response, strlen(response), 0);

    save_users_to_file(users_list);
    printf("[HINT] Register success：ID=%d, Name=%s\n", new_user.user_id, new_user.user_name);
    free(info);    
}


// 用户登陆处理函数
void handle_login(int client_fd, const char *data) 
{
    //格式：LOGIN_CMD|USER|PWD
    char *info = strdup(data + strlen(LOGIN_CMD));
    char *username = strtok(info, "|");
    char *password = strtok(NULL, "|");
    
    int login_success = 0;
    node_t *result_list = NULL;
    users_t *matched_user = NULL; 
    online_node_t *online_user = NULL;  

    if (!username || !password) 
    {
        send(client_fd, "LOGIN_FAILED: Incorrect command format（USER|PWD）", 
             strlen("LOGIN_FAILED: Incorrect command format（USER|PWD）"), 0);
        free(info);
        return;
    }

    pthread_mutex_lock(&users_mutex);
    
    users_t temp = {.user_name = ""};  
    strncpy(temp.user_name, username, sizeof(temp.user_name) - 1);
    temp.user_name[sizeof(temp.user_name) - 1] = '\0';

    result_list  = find_user(users_list, cmpUser_Name ,&temp);
    //如果匹配到用户
    if (result_list) 
    {
        node_t *current = result_list->after;
        users_t *user = NULL;
        while (current != result_list) 
        {
            user = (users_t *)current->data;
            if (strcmp(user->user_pw, password) == 0) 
            {
                login_success = 1;
                matched_user = (users_t *)malloc(sizeof(users_t));
                SYSERR2(NULL, ==, matched_user,"malloc failed", break);
                memcpy(matched_user, user, sizeof(users_t));
                break;
            }
            current = current->after;
        }
            
        // 销毁结果链表
        destroy_dlist(&result_list);
    }

    pthread_mutex_unlock(&users_mutex);
    
    if (matched_user != NULL) 
    {
        printf("[LOGIN]matched_user %d %s %s\n", 
               matched_user->user_id, 
               matched_user->user_name, 
               matched_user->user_pw);
    } 
    else 
    {
        printf("[LOGIN]No matching user found\n");
    }

    if (login_success && matched_user != NULL) 
    {
        online_user = (online_node_t *)malloc(sizeof(online_node_t));
        if (online_user == NULL) 
        {
            perror("malloc for online_user failed");
            login_success = 0;  // 分配失败标记登录失败
        } 
        else 
        {
            // 设置在线用户信息
            online_user->u_data = matched_user;  // 关联用户数据
            online_user->is_online = 1;          // 标记为在线
            online_user->client_fd = client_fd;  // 保存客户端文件描述符（整数类型）
        }
    }

    // 返回登录结果
    if (login_success && online_user != NULL) 
    {   
        pthread_mutex_lock(&online_mutex);
        // 将在线用户节点插入链表
        insert_tdlist(online_list, online_user, sizeof(online_node_t));
        pthread_mutex_unlock(&online_mutex);
        
        // 构造响应字符串 格式：LOGIN_SUCCESS|ID|NAME
        char response[128] = {0};
        snprintf(response, sizeof(response), 
             "LOGIN_SUCCESS|%d|%s", 
             matched_user->user_id,
             matched_user->user_name);

        send(client_fd, response, strlen(response), 0);
        printf("[HINT] Login success：%s\n", username);
    } 
    else 
    {
        send(client_fd, "LOGIN_FAILED", strlen("LOGIN_FAILED"), 0);
        printf("[HINT] Login error：%s\n", username);
        
        // 释放已分配的内存
        if (matched_user != NULL) 
        {
            free(matched_user);
        }
        if (online_user != NULL) 
        {
            free(online_user);
        }
    }
    
    free(info);
}


// 用户登出处理函数
void handle_logout(int client_fd, const char *data) 
{
    // 解析指令格式: LOGOUT|用户ID
    char *user_id_str = strtok((char*)data + strlen(LOGOUT_CMD), "|");
    if (!user_id_str) 
    {
        send(client_fd, "[LOGOUT_FAILED]Invalid command format", strlen("LOGOUT_FAILED: Invalid command format"), 0);
        return;
    }
    int target_user_id = atoi(user_id_str);
    int logout_success = 0;

    //标记在线用户为离线状态
    pthread_mutex_lock(&online_mutex);
    node_t *current_online = online_list->after;

    while (current_online != online_list) 
    {
        online_node_t *online_user = (online_node_t *)current_online->data;
        if (online_user && online_user->u_data && online_user->u_data->user_id == target_user_id) 
        {
            online_user->is_online = 0;  
            logout_success = 1;
            break;
        }
        current_online = current_online->after;
    }
    pthread_mutex_unlock(&online_mutex);

    // 更新用户表状态
    if (logout_success) 
    {
        pthread_mutex_lock(&users_mutex);
        users_t temp_user = {.user_id = target_user_id};
        node_t *result = find_user(users_list, cmpUser_ID, &temp_user);
        if (result) 
        {
            node_t *user_node = result->after;
            while (user_node != result) 
            {
                users_t *user = (users_t *)user_node->data;
                if (user->user_id == target_user_id) 
                {
                    user->user_state = 0;  // 标记为离线
                    break;
                }
                user_node = user_node->after;
            }
            destroy_dlist(&result);  
        }
        pthread_mutex_unlock(&users_mutex);

        // 保存用户数据
        save_users_to_file(users_list);
    }

    // 4. 发送响应
    if (logout_success) 
    {
        send(client_fd, "[LOGOUT_SUCCESS]Successfully logged out", strlen("LOGOUT_SUCCESS: Successfully logged out"), 0);
        printf("[HINT]User %d logout success\n", target_user_id);
    } 
    else 
    {
        send(client_fd, "[LOGOUT_FAILED]User not online", strlen("LOGOUT_FAILED: User not online"), 0);
    }
}


// 显示用户处理
void handle_show_user(int client_fd, const char *data) 
{
    // 格式：SHOW_USER|排序方式 （1=按ID，2=按用户名）
    int sort_type = atoi(data + strlen(SHOW_USER_CMD));
    cmpfun_t cmp_func = NULL;
    char response[4096] = {0};
    char *resp_ptr = response;  

    // 选择排序函数
    if (sort_type == 1) 
    {
        cmp_func = cmpUser_ID;
    } 
    else if (sort_type == 2) 
    {
        cmp_func = cmpUser_Name;
    } 
    else 
    {
        send(client_fd, "[SORT] Invalid sorting method", strlen("[SORT] Invalid sorting method"), 0);
        return;
    }

    pthread_mutex_lock(&users_mutex);  

    // 排序用户列表
    if (sort_user(users_list, cmp_func) != 0) 
    {
        snprintf(response, sizeof(response), "There is no user data currently");
        pthread_mutex_unlock(&users_mutex);
        send(client_fd, response, strlen(response), 0);
        return;
    }

    // 构造响应字符串
    // 格式： SHOW_USER|序号|ID|姓名|性别|年龄|电话|邮箱|居住地|好友数|状态
    resp_ptr += snprintf(resp_ptr, sizeof(response) - (resp_ptr - response),
        "%-4s %-6s %-8s %-5s %-7s %-12s %-17s %-8s %-8s %-6s\n",
        "Order", "ID", "Name", "Sex", "Age", "Phone", "Email", "Place", "Friend", "Status");

    // 遍历排序后的用户列表，拼接用户数据
    node_t *current = users_list->after;
    while (current != users_list) 
    {
        users_t *user = (users_t *)current->data;
        if (user) 
        {
            // 转换状态为文字描述
            const char *status_str = (user->user_state == 1) ? "Online" : "Offline";
            // 拼接一行用户数据
            // 格式： 序号|ID|姓名|性别|年龄|电话|邮箱|居住地|好友数|状态
            resp_ptr += snprintf(resp_ptr, sizeof(response) - (resp_ptr - response),
                "%-4d %-6d %-10s %-5c %-5d %-10s  %-18s  %-8s %-6d %-6s\n",
                user->user_order,      // 序号
                user->user_id,         // ID
                user->user_name,       // 用户名
                user->sex,             // 性别
                user->user_age,        // 年龄
                user->user_phone,      // 手机号
                user->user_email,      // 邮箱
                user->user_place,      // 居住地
                user->user_friend_num, // 好友数
                status_str);           // 状态（
        }
        current = current->after;
    }

    pthread_mutex_unlock(&users_mutex);  // 解锁

    send(client_fd, response, strlen(response), 0);
}


//用户查询处理函数
void handle_find(int client_fd, const char *data) 
{
    // 解析指令：FIND_USER|方式|值
    char *cmd = strdup(data);
    char *type_str = strtok(cmd + strlen(FIND_USER_CMD), "|");
    char *target = strtok(NULL, "|");
    char response[4096] = {0};
    int find_count = 0;

    printf("[SERVER] Received find command: %s (length: %s)\n", type_str, target);
    if (!type_str || !target) 
    {
        send(client_fd, "[FIND_FAILED] Incorrect command format", strlen("[FIND_FAILED] Incorrect command format"), 0);
        free(cmd);
        return;
    }

    int find_type = atoi(type_str);
    users_t temp_user = {0};
    cmpfun_t cmp_func = NULL;

    // 根据查询方式设置比较函数
    switch (find_type) 
    {
        case 1:  // 按ID
            temp_user.user_id = atoi(target);
            cmp_func = cmpUser_ID;
            break;
        case 2:  // 按用户名
            strncpy(temp_user.user_name, target, sizeof(temp_user.user_name)-1);
            cmp_func = cmpUser_Name;
            break;
        case 3:  // 按手机号
            strncpy(temp_user.user_phone, target, sizeof(temp_user.user_phone)-1);
            cmp_func = cmpUser_Phone;
            break;
        default:
            send(client_fd, "FIND_FAILED: Invalid query method", strlen("FIND_FAILED: Invalid query method"), 0);
            free(cmd);
            return;
    }

    pthread_mutex_lock(&users_mutex);  // 加锁保护

    // 查找匹配的用户
    node_t *result_list = find_user(users_list, cmp_func, &temp_user);

    if (result_list && result_list->after != result_list) 
    {
        // 构建查询结果字符串
        char header[] = "序号  ID      用户名    性别     年龄   手机号      邮箱             居住地     好友数   群聊数   状态\n";
        char line[512] = {0};
        strcpy(response, "FIND_SUCCESS|");
        strcat(response, header);

        node_t *current = result_list->after;
        while (current != result_list) 
        {
            users_t *user = (users_t *)current->data;
            find_count++;
            
            // 格式化一行用户信息
            snprintf(line, sizeof(line), 
                     "%-4d  %-6d  %-10s  %-5c  %-5d  %-11s  %-16s  %-10s  %-6d  %-6d  %s\n",
                     find_count,
                     user->user_id,
                     user->user_name,
                     user->sex,
                     user->user_age,
                     user->user_phone,
                     user->user_email,
                     user->user_place,
                     user->user_friend_num,
                     user->user_group_num,
                     user->user_state == 1 ? "在线" : "离线");
            
            strcat(response, line);
            current = current->after;
        }
    } 
    else 
    {
        snprintf(response, sizeof(response), "[FIND_FAILED] No matching user found");
    }
    
    destroy_dlist(&result_list);  
    pthread_mutex_unlock(&users_mutex);  
    free(cmd);
    // 格式：FIND_SUCCESS|序号  ID    用户名      性别  年龄  手机号      邮箱             居住地    好友数  群聊数  状态
    send(client_fd, response, strlen(response), 0);
}


// 用户删除处理函数
void handle_delete(int client_fd, const char *data) 
{
    // 格式: DELETE|方式|值
    char *method = strtok((char*)data + strlen(DELETE_CMD), "|");
    char *value = strtok(NULL, "|");
    int delete_success = 0;
    users_t temp_user = {0};

    if (!method || !value) 
    {
        send(client_fd, "[DELETE_FAILED] Invalid command format", strlen("[DELETE_FAILED] Invalid command format"), 0);
        return;
    }

    pthread_mutex_lock(&users_mutex);  
    
    if (strcmp(method, "NAME") == 0) 
    {
        strncpy(temp_user.user_name, value, sizeof(temp_user.user_name)-1);
        if(del_user(users_list, cmpUser_Name, &temp_user) == 0)
            delete_success = 1;
    } 
    else if (strcmp(method, "ID") == 0) 
    {
        temp_user.user_id = atoi(value);
        if(del_user(users_list, cmpUser_ID, &temp_user) == 0)
            delete_success = 1;
    } 
    else if (strcmp(method, "PHONE") == 0) 
    {
        strncpy(temp_user.user_phone, value, sizeof(temp_user.user_phone)-1);
        if(del_user(users_list, cmpUser_Phone, &temp_user) == 0)
            delete_success = 1;
    } 
    else 
    {
        send(client_fd, "[DELETE_FAILED] Invalid method", strlen("[DELETE_FAILED] Invalid method"), 0);
        return;
    }

    pthread_mutex_unlock(&users_mutex); 

    // 返回结果
    if (delete_success) 
    {
        send(client_fd, "[DELETE_SUCCESS] User deleted", strlen("[DELETE_SUCCESS] User deleted"), 0);
    } 
    else 
    {
        send(client_fd, "[DELETE_FAILED] User not found", strlen("[DELETE_FAILED] User not found"), 0);
    }

    save_users_to_file(users_list);
}


// 获取在线列表处理函数
void handle_get_online(int client_fd) 
{
    pthread_mutex_lock(&online_mutex);
    
    // 统计在线用户数量
    int online_count = 0;
    node_t *current = online_list->after;
    while (current != online_list) 
    {
        online_node_t *online_user = (online_node_t *)current->data;
        if (online_user && online_user->is_online == 1 && online_user->u_data) 
        {
            online_count++;
        }
        current = current->after;
    }
    
    // 构建响应数据（
    //格式：ONLINE|在线用户数
    char response[2048] = {0};
    unsigned int pos = snprintf(response, sizeof(response), "ONLINE|%d", online_count);
    
    // 填充在线用户信息
    current = online_list->after;
    int index = 1;
    while (current != online_list && pos < sizeof(response) - 1) 
    {
        online_node_t *online_user = (online_node_t *)current->data;
        if (online_user && online_user->is_online == 1 && online_user->u_data) 
        {
            // 追加：ONLINE|在线用户数|序号|ID|姓名
            pos += snprintf(response + pos, sizeof(response) - pos,
                          "|%d|%d|%s",
                          index,
                          online_user->u_data->user_id,
                          online_user->u_data->user_name);
            index++;
        }
        current = current->after;
    }
    
    pthread_mutex_unlock(&online_mutex);
    
    // 发送响应给客户端
    send(client_fd, response, strlen(response), 0);
}


// 私聊请求处理函数
void handle_private_request(int client_fd, const char *data) 
{
    // 解析指令格式: PRIVATE_REQUEST|发起方ID|目标方ID
    char *sender_id_str = strtok((char*)data + strlen(PRIVATE_REQUEST), "|");
    char *target_id_str = strtok(NULL, "|");
    
    if (!sender_id_str || !target_id_str) 
    {
        send(client_fd, "[PRIVATE_FAILED] Invalid command format", 
             strlen("[PRIVATE_FAILED] Invalid command format"), 0);
        return;
    }
    
    int target_id = atoi(target_id_str);
    int sender_id = atoi(sender_id_str);
    
    pthread_mutex_lock(&online_mutex);
    
    // 查找目标用户是否在线
    int target_found = 0;
    int target_fd = -1;
    char target_name[32] = {0};
    char sender_name[32] = {0};
    
    node_t *current = online_list->after;
    while (current != online_list) 
    {
        online_node_t *online_user = (online_node_t *)current->data;
        if (online_user && online_user->is_online && online_user->u_data) 
        {
            if (online_user->u_data->user_id == target_id) 
            {
                target_found = 1;
                target_fd = online_user->client_fd;
                strncpy(target_name, online_user->u_data->user_name, sizeof(target_name)-1);
                printf("[PRI_REQ] Target user found: ID=%d, Name=%s, Socket=%d\n", 
                       target_id, target_name, target_fd);
            }
            if (online_user->u_data->user_id == sender_id) 
            {
                strncpy(sender_name, online_user->u_data->user_name, sizeof(sender_name)-1);
                printf("[PRI_REQ] Sender user found: ID=%d, Name=%s\n", sender_id, sender_name);
            }
        }
        current = current->after;
    }
    
    pthread_mutex_unlock(&online_mutex);
    
    if (target_found) 
    {
        // 向目标用户发送私聊请求
        // 格式：PRIVATE_REQUEST|发起方ID|发起方姓名
        char request_msg[128] = {0};
        snprintf(request_msg, sizeof(request_msg), 
                 "PRIVATE_REQUEST|%d|%s", sender_id, sender_name);
        
        printf("[PRI_REQ] Sending private chat request to target user: %s\n", request_msg);
        
        if (send(target_fd, request_msg, strlen(request_msg), 0) < 0) 
        {
            perror("[PRI_REQ] Failed to send private chat request");
            send(client_fd, "[PRIVATE_FAILED] Send error", 
                 strlen("[PRIVATE_FAILED] Send error"), 0);
        } 
        else 
        {
            // 通知发起方请求已发送
            // 格式: PRIVATE_REQUEST_SENT|目标方ID|目标方姓名
            char response[128] = {0};
            snprintf(response, sizeof(response), 
                     "PRIVATE_REQUEST_SENT|%d|%s", target_id, target_name);
            send(client_fd, response, strlen(response), 0);
            printf("[PRI_REQ] Private chat request has been sent to the target user\n");
        }
    } 
    else 
    {
        // 目标用户不在线
        printf("[PRI_REQ] Target user %d is not online\n", target_id);
        send(client_fd, "USER_OFFLINE", strlen("USER_OFFLINE"), 0);
    }
}


// 私聊接受处理函数
void handle_private_accept(int client_fd, const char *data) 
{
    // 格式: PRIVATE_ACCEPT|接受方ID|发起方ID
    char *acceptor_id_str = strtok((char*)data + strlen(PRIVATE_ACCEPT), "|");
    char *sender_id_str = strtok(NULL, "|");
    
    if (!acceptor_id_str || !sender_id_str) 
    {
        send(client_fd, "[PRIVATE_ACCEPT_FAILED] Invalid format", 
             strlen("[PRIVATE_ACCEPT_FAILED] Invalid format"), 0);
        return;
    }
    
    int sender_id = atoi(sender_id_str);
    int acceptor_id = atoi(acceptor_id_str);
    
    printf("[PRI_ACCEPT] Private chat acceptance: Acceptor=%d, Initiator=%d\n", acceptor_id, sender_id);
    
    pthread_mutex_lock(&online_mutex);
    
    // 查找发起方用户
    int sender_found = 0;
    int sender_fd = -1;
    char acceptor_name[32] = {0};
    
    node_t *current = online_list->after;
    while (current != online_list) 
    {
        online_node_t *online_user = (online_node_t *)current->data;
        if (online_user && online_user->is_online && online_user->u_data) 
        {
            if (online_user->u_data->user_id == sender_id) 
            {
                sender_found = 1;
                sender_fd = online_user->client_fd;
                printf("[PRI_ACCEPT] Initiating user found: ID=%d, Socket=%d\n", sender_id, sender_fd);
            }
            if (online_user->u_data->user_id == acceptor_id) 
            {
                strncpy(acceptor_name, online_user->u_data->user_name, sizeof(acceptor_name)-1);
                printf("[PRI_ACCEPT] Accepting user found: ID=%d, Name=%s\n", acceptor_id, acceptor_name);
            }
        }

        current = current->after;
    }
    
    pthread_mutex_unlock(&online_mutex);
    
    if (sender_found) 
    {
        // 通知发起方对方已接受私聊
        // 格式: PRIVATE_ACCEPT|接受方ID|发起方ID
        char accept_msg[128] = {0};
        snprintf(accept_msg, sizeof(accept_msg), 
                 "PRIVATE_ACCEPT|%d|%s", acceptor_id, acceptor_name);
        
        printf("[PRI_ACCEPT] To initiator: %s\n", accept_msg);
        
        if (send(sender_fd, accept_msg, strlen(accept_msg), 0) < 0) 
        {
            perror("[PRI_ACCEPT] Failed to notify initiator");
        } 
        else 
        {
            printf("[PRI_ACCEPT] User %d accepted the private chat request from user %d\n", acceptor_id, sender_id);
        }
    }
    
    // 确认接受
    send(client_fd, "PRIVATE_ACCEPT_OK", strlen("PRIVATE_ACCEPT_OK"), 0);
}


// 私聊拒绝处理函数
void handle_private_refuse(int client_fd, const char *data) 
{
    // 格式: PRIVATE_REFUSE|拒绝方ID|发起方ID
    char *refuser_id_str = strtok((char*)data + strlen(PRIVATE_REFUSE), "|");
    char *sender_id_str = strtok(NULL, "|");
    
    if (!refuser_id_str || !sender_id_str) 
    {
        send(client_fd, "[PRIVATE_REFUSE_FAILED] Invalid format", 
             strlen("[PRIVATE_REFUSE_FAILED] Invalid format"), 0);
        return;
    }
    
    int sender_id = atoi(sender_id_str);
    int refuser_id = atoi(refuser_id_str);
    
    pthread_mutex_lock(&online_mutex);
    
    // 查找发起方用户
    int sender_found = 0;
    int sender_fd = -1;
    
    node_t *current = online_list->after;
    while (current != online_list) 
    {
        online_node_t *online_user = (online_node_t *)current->data;
        if (online_user && online_user->is_online && online_user->u_data) 
        {
            if (online_user->u_data->user_id == sender_id) 
            {
                sender_found = 1;
                sender_fd = online_user->client_fd;
                break;
            }
        }
        current = current->after;
    }
    
    pthread_mutex_unlock(&online_mutex);
    
    if (sender_found) 
    {
        // 通知发起方对方已拒绝私聊
        // 格式: PRIVATE_REFUSE|拒绝方ID
        char refuse_msg[64] = {0};
        snprintf(refuse_msg, sizeof(refuse_msg), 
                 "PRIVATE_REFUSE|%d", refuser_id);
        send(sender_fd, refuse_msg, strlen(refuse_msg), 0);
    }
    
    // 确认拒绝
    send(client_fd, "PRIVATE_REFUSE_OK", strlen("PRIVATE_REFUSE_OK"), 0);
}


// 私聊消息处理函数
void handle_private_msg(int client_fd, const char *data) 
{
    // 解析指令格式: PRIVATE_MSG|发送方ID|接收方ID|消息内容
    char *sender_id_str = strtok((char*)data + strlen(PRIVATE_MSG), "|");
    char *target_id_str = strtok(NULL, "|");
    char *message = strtok(NULL, "|");
    
    if (!sender_id_str || !target_id_str || !message) 
    {
        send(client_fd, "[PRIVATE_MSG_FAILED] Invalid format", 
             strlen("[PRIVATE_MSG_FAILED] Invalid format"), 0);
        return;
    }
    
    int target_id = atoi(target_id_str);
    int sender_id = atoi(sender_id_str);
    
    printf("[PRI_MSG]Received private message: Sender=%d, Receiver=%d, Message=%s\n", sender_id, target_id, message);
    
    pthread_mutex_lock(&online_mutex);
    
    // 查找目标用户
    int target_found = 0;
    int target_fd = -1;
    char target_name[32] = {0};
    
    node_t *current = online_list->after;
    while (current != online_list) 
    {
        online_node_t *online_user = (online_node_t *)current->data;
        if (online_user && online_user->is_online && online_user->u_data) 
        {
            if (online_user->u_data->user_id == target_id) 
            {
                target_found = 1;
                target_fd = online_user->client_fd;
                strncpy(target_name, online_user->u_data->user_name, sizeof(target_name)-1);
                //printf("[PRI_MSG] Taget user found: ID=%d, Name=%s, Socket=%d\n",target_id, target_name, target_fd);
                break;
            }
        }
        current = current->after;
    }
    
    pthread_mutex_unlock(&online_mutex);
    
    if (target_found) 
    {
        // 转发消息给目标用户
        // 格式: PRIVATE_MSG|发送方ID|消息内容
        char forward_msg[1024] = {0};
        snprintf(forward_msg, sizeof(forward_msg), 
                 "PRIVATE_MSG|%d|%s", sender_id, message);
        
        //printf("[PRI_MSG] Forwarding message to target user: %s\n", forward_msg);
        
        if (send(target_fd, forward_msg, strlen(forward_msg), 0) < 0) 
        {
            perror("[PRI_MSG] Forwarding message failed");
            send(client_fd, "[PRIVATE_MSG_FAILED] Forward error", 
                 strlen("[PRIVATE_MSG_FAILEDD] Forward error"), 0);
        } 
        else 
        {
            // 确认消息已发送
            send(client_fd, "PRIVATE_MSG_SENT", strlen("PRIVATE_MSG_SENT"), 0);
            printf("[PRI_MSG] Forwarding message success\n");
        }
    } 
    else 
    {
        // 目标用户不在线
        printf("[PRI_MSG] Target user %d is not online\n", target_id);
        send(client_fd, "USER_OFFLINE", strlen("USER_OFFLINE"), 0);
    }
}


// 私聊退出处理函数
void handle_private_exit(int client_fd, const char *data) 
{
    // 格式: PRIVATE_EXIT|用户ID|目标用户ID
    char *user_id_str = strtok((char*)data + strlen(PRIVATE_EXIT), "|");
    char *target_id_str = strtok(NULL, "|");
    
    if (!user_id_str || !target_id_str) 
    {
        send(client_fd, "[PRIVATE_EXIT_FAILED] Invalid format", 
             strlen("[PRIVATE_EXIT_FAILED] Invalid format"), 0);
        return;
    }
    
    int target_id = atoi(target_id_str);
    int user_id = atoi(user_id_str);
    
    pthread_mutex_lock(&online_mutex);
    
    // 查找目标用户
    int target_found = 0;
    int target_fd = -1;
    
    node_t *current = online_list->after;
    while (current != online_list) 
    {
        online_node_t *online_user = (online_node_t *)current->data;
        if (online_user && online_user->is_online && online_user->u_data) 
        {
            if (online_user->u_data->user_id == target_id) 
            {
                target_found = 1;
                target_fd = online_user->client_fd;
                break;
            }
        }
        current = current->after;
    }
    
    pthread_mutex_unlock(&online_mutex);
    
    if (target_found) 
    {
        // 通知目标用户对方已退出私聊
        // 格式: PRIVATE_EXIT|用户ID
        char exit_msg[64] = {0};
        snprintf(exit_msg, sizeof(exit_msg), 
                 "PRIVATE_EXIT|%d", user_id);
        send(target_fd, exit_msg, strlen(exit_msg), 0);
    }
    
    // 确认退出
    send(client_fd, "PRIVATE_EXIT_OK", strlen("PRIVATE_EXIT_OK"), 0);
}


// 私聊查看信息处理函数
void handle_user_info(int client_fd, const char *data) 
{
    // 解析指令格式: USER_INFO|请求方ID|目标用户ID
    char *requester_id_str = strtok((char*)data + strlen(USER_INFO_CMD), "|");
    char *target_id_str = strtok(NULL, "|");
    
    if (!requester_id_str || !target_id_str) 
    {
        send(client_fd, "[USER_INFO_FAILED] Invalid command format", 
             strlen("[USER_INFO_FAILED] Invalid command format"), 0);
        return;
    }
    
    int target_id = atoi(target_id_str);
    //int requester_id = atoi(requester_id_str);
    
    pthread_mutex_lock(&users_mutex);
    
    // 查找目标用户信息
    users_t temp_user = {.user_id = target_id};
    node_t *result_list = find_user(users_list, cmpUser_ID, &temp_user);
    
    char response[512] = {0};
    
    if (result_list && result_list->after != result_list) 
    {
        users_t *user = (users_t *)result_list->after->data;
        
        // 构建用户信息响应
        // 格式: USER_INFO|ID|姓名|年龄|性别|手机号|邮箱|居住地|好友数|群聊数|状态
        snprintf(response, sizeof(response), 
                 "USER_INFO|%d|%s|%d|%c|%s|%s|%s|%d|%d|%s",
                 user->user_id,
                 user->user_name,
                 user->user_age,
                 user->sex,
                 user->user_phone,
                 user->user_email,
                 user->user_place,
                 user->user_friend_num,
                 user->user_group_num,
                 user->user_state == 1 ? "Online" : "Offline");
    } 
    else 
    {
        snprintf(response, sizeof(response), "USER_INFO_FAILED|User not found");
    }
    
    if (result_list) 
    {
        destroy_dlist(&result_list);
    }
    
    pthread_mutex_unlock(&users_mutex);
    
    // 发送响应
    send(client_fd, response, strlen(response), 0);
}


// 查找用户辅助函数
node_t *find_user(node_t *head, cmpfun_t cmpfun, const users_t *user)
{
    SYSERR(NULL,==,head,"head is NULL",NULL);
    SYSERR(NULL,==,user,"dev is NULL",NULL);
	node_t *result_list = create_dlist();
	node_t *temp = head->after;
    
	while( temp != head )
	{
        if (cmpfun(temp->data, user) == 0) 
        {
            users_t *original_user = (users_t *)temp->data;
            // 1. 为新数据分配独立内存
            users_t *copied_user = (users_t *)malloc(sizeof(users_t));
            SYSERR2(NULL, ==, copied_user, "malloc failed in find_user", destroy_dlist(&result_list);return NULL);
            // 2. 复制原数据到新内存
            memcpy(copied_user, original_user, sizeof(users_t));
            // 3. 将副本插入结果链表
            insert_tdlist(result_list, copied_user, sizeof(users_t));
        }
        temp = temp->after;  
	}
    
    // 如果结果链表为空，销毁并返回NULL
    if (result_list->after == result_list) 
    {
        destroy_dlist(&result_list);
        return NULL;
    }

    return result_list;
}


// 排序辅助函数
int sort_user(node_t *head, cmpfun_t cmpfun) 
{
    SYSERR(NULL, ==, head, "head is NULL", -1);

    //底层链表的选择排序函数
    selectSort_dlist(head, cmpfun);

    // 获取有效节点数
    int n = 0;
    node_t *count_temp = head->after;  
    while (count_temp != head && count_temp != NULL) 
    { 
        n++;
        count_temp = count_temp->after;
    }
    SYSERR2(n, ==, 0, "no users", return -1);

    // 赋值序号
    node_t *temp = head->after;  
    for (int i = 1; i <= n; i++) 
    {  
        // 避免空节点
        if (temp == NULL || temp->data == NULL) 
        {
            break;  
        }
        users_t *user_data = (users_t *)temp->data;
        user_data->user_order = i;  

        // 移动到下一个节点
        temp = temp->after;
        if (temp == head) 
        { 
            break;
        }
    }

    return 0;
}


// 删除辅助函数
int del_user(node_t *head, cmpfun_t cmpfun, const users_t *dev)
{
    SYSERR(NULL,==,head,"head is NULL",-1);
    SYSERR(NULL,==,dev,"user is NULL",-2);
    node_t *result;
    int delete_count = 0;  
    
    while ((result = delete_vdlist(head, dev, cmpfun)) != NULL)
    {
        delete_count++; 
    }
    
    if (delete_count == 0)
        return -1;  
    else
        return 0;   
}


// 比较辅助函数
int cmpUser_Name(const void *data1,const void *data2)
{
    const users_t *userp1 = (const users_t *)data1;
	const users_t *userp2 = (const users_t *)data2;
	return strcmp(userp1->user_name,userp2->user_name);
}
int cmpUser_ID(const void *data1, const void *data2)
{
    const users_t *userp1 = (const users_t *)data1;
	const users_t *userp2 = (const users_t *)data2;
	return userp1->user_id - userp2->user_id;
}
int cmpUser_Phone(const void *data1, const void *data2)
{
    const users_t *userp1 = (const users_t *)data1;
	const users_t *userp2 = (const users_t *)data2;
	return strcmp(userp1->user_phone,userp2->user_phone);
}
